﻿using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;
using Yoozoo.Core.Extensions.CSharp;

namespace Yoozoo.Extension
{
    [Serializable]
    public class MaterialChangeGroup
    {
        [SerializeField]
        private Renderer[] renderers;
        [SerializeField]
        private Graphic[] graphics;
        [SerializeField]
        private Material[] materials;

        private int materialIndex;

#if UNITY_EDITOR
        public bool FindTexts(GameObject holder)
        {
            var texts = holder.GetComponentsInChildren<Text>(true);
            if (texts.IsEmpty())
                return false;

            graphics = new Graphic[texts.Length];
            for (var i = 0; i < texts.Length; i++)
                graphics[i] = texts[i];

            materials = new[]
            {
                AssetDatabase.LoadAssetAtPath<Material>("Assets/ResourcesAssets/Materials/mat_YTextDefault.mat"),
                AssetDatabase.LoadAssetAtPath<Material>("Assets/ResourcesAssets/Materials/mat_YTextDefaultGray.mat")
            };

            materialIndex = 0;
            return true;
        }

        public bool FindImages(GameObject holder)
        {
            var images = holder.GetComponentsInChildren<Image>(true);
            if (images.IsEmpty())
                return false;

            graphics = new Graphic[images.Length];
            for (var i = 0; i < images.Length; i++)
                graphics[i] = images[i];

            materials = new[]
            {
                AssetDatabase.LoadAssetAtPath<Material>(
                    "Packages/com.yoozoo.owl.rendering.hrp/RenderPipeline/Materials/UIDefault.mat"),
                AssetDatabase.LoadAssetAtPath<Material>("Assets/ResourcesAssets/UI/Material/mat_DefaultGrey.mat")
            };

            materialIndex = 0;
            return true;
        }


        public bool FindRenderers(GameObject holder)
        {
            renderers = holder.GetComponentsInChildren<Renderer>(true);
            if (renderers.IsEmpty())
                return false;
            materials = new Material[2];
            return true;
        }
#endif

        public void SelectMaterial(int index)
        {
            if (index == materialIndex)
            {
                return;
            }

            if (materials.IsEmpty())
                return;

            if (index < 0 || index >= materials.Length)
                return;

            var material = materials[index];

            if (renderers != null)
            {
                foreach (var r in renderers)
                {
                    r.material = material;
                }
            }

            if (graphics != null)
            {
                foreach (var graphic in graphics)
                {
                    graphic.material = material;
                }
            }

            materialIndex = index;
        }
    }

    public class MaterialChanger : MonoBehaviour
    {
        [SerializeField]
        private List<MaterialChangeGroup> groups = new List<MaterialChangeGroup>();

        [SerializeField]
        private int materialIndex;

        public void SelectMaterial(int index)
        {
            if (index == materialIndex)
            {
                return;
            }

            foreach (var changeGroup in groups)
            {
                changeGroup.SelectMaterial(index);
            }

            materialIndex = index;
        }


#if UNITY_EDITOR
        private void OnValidate()
        {
            Initialize();

            foreach (var changeGroup in groups)
                changeGroup.SelectMaterial(materialIndex);
        }

        private void Initialize()
        {
            if (groups.IsNotEmpty())
            {
                return;
            }

            var group = new MaterialChangeGroup();
            if (group.FindImages(gameObject))
            {
                groups.Add(group);
            }

            group = new MaterialChangeGroup();
            if (group.FindRenderers(gameObject))
            {
                groups.Add(group);
            }

            group = new MaterialChangeGroup();
            if (group.FindTexts(gameObject))
            {
                groups.Add(group);
            }
        }
#endif
    }
}
